package agngui.tools;

/**
 * A Range object that encapsulates the information necessary to range a value from
 * a lower bound to an upper bound with a given step size
 * 
 * @author Ben Bloom
 */
public class Range {
	/**
	 * the lower bound of the range
	 */
	private final double lower;
	
	/**
	 * the upper bound of the range
	 */
	private final double upper;
	
	/**
	 * the step size of the range
	 */
	private final double step;
	
	/**
	 * the current value of the ranging parameter
	 */
	private double current;
	
	/**
	 * constructs a new range
	 * 
	 * @param low The lower bound
	 * @param high The upper bound
	 * @param step The step size
	 */
	public Range(double low, double high, double step) {
		lower = low;
		upper = high;
		if(step <= 0) {
			throw new IllegalArgumentException("Step size must be greater than zero");
		}
		this.step = step;
		current = lower;
	}
	
	/**
	 * Calculates and returns the number of chunks that this range will break into
	 * 
	 * @return The number of chunks that this range will be split into
	 */
	public int numChunks() { return (int)Math.floor(1 + (upper - lower) / step); }//want the range from lower through upper (inclusive)
	
	/**
	 * gives the lower bound of this range
	 * 
	 * @return The lower bound
	 */
	public double lower() { return lower; }
	
	/**
	 * gives the upper bound of this range
	 * 
	 * @return The upper bound
	 */
	public double upper() { return upper; }
	
	/**
	 * gives the step size of this range
	 * 
	 * @return The step size
	 */
	public double stepSize() { return step; }
	
	/**
	 * gives the current value of this range
	 * 
	 * @return The current value of the range
	 */
	public double current() { return current; }
	
	/**
	 * performs a step by updating the current value of the range
	 */
	public void doStep() { current += step; }
	
	/**
	 * resets the current value of the range to be the lower bound of the range
	 */
	public void resetCurrentToLower() { current = lower; }
}